﻿using Dino;
using NUnit.Framework;
using Rhino.Mocks;

namespace Tests.Dino.UnitOfWorkTests
{
    public partial class UnitOfWorkTests
    {
        [TestFixture]
        public class WhenGettingAnObjectContext
        {
            private UnitOfWork _unitOfWork;
            private bool _created;
            private IObjectContext _context;

            [SetUp]
            public void Setup()
            {
                _context = new TestContext();
            }

            [Test]
            [ExpectedException(typeof(ContextNotRegisteredException))]
            public void TheRequestedContextHasNotBeenRegistered()
            {
                _unitOfWork = UnitOfWork.Configure().Initialize();

                _unitOfWork.GetContext<TestContext>();
            }

            [Test]
            public void CreatesContextFromRegisteredFactory()
            {
                _unitOfWork = UnitOfWork.Configure(c => c.WithContext<TestContext>(() =>
                    {
                        _created = true;
                        return _context;
                    })).Initialize();

                var result = _unitOfWork.GetContext<TestContext>();

                Assert.IsTrue(_created);
                Assert.AreSame(_context, result);
            }

            [Test]
            public void CreatesAndCachedContext()
            {
                int timesCreated = 0;
                _unitOfWork = UnitOfWork.Configure(c => c.WithContext<TestContext>(() =>
                    {
                        timesCreated++;
                        _created = true;
                        return _context;
                    })).Initialize();

                var firstGetContextResult = _unitOfWork.GetContext<TestContext>();
                var secondGetContextResult = _unitOfWork.GetContext<TestContext>();

                Assert.AreEqual(1, timesCreated);
                Assert.IsTrue(_created);
                Assert.AreSame(_context, firstGetContextResult);
                Assert.AreSame(firstGetContextResult, secondGetContextResult);
            }
        }
    }
}